import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:orginone/components/XImage/XImage.dart';
import 'package:orginone/components/XLazy/XLazy.dart';
import 'package:orginone/config/theme/unified_style.dart';
import 'package:orginone/dart/base/schema.dart';
import 'package:orginone/dart/core/public/entity.dart';
import 'package:orginone/routers/pages.dart';

import '../../pages/home/components/BadgeTabWidget/BadgeTabWidget.dart';
import '../EmptyWidget/EmptyWidget.dart';
import '../XText/XText.dart';
import 'components/ListItemWidget.dart';

class ListWidget<T> extends StatefulWidget {
  List<T>? initDatas;
  // 列表数据
  FutureOr<List<T>> Function([dynamic data])? getDatas;
  // // 列表数据
  // Future<List<T>> Function([T? data])? getLazyDatas;
  // 加载更多
  FutureOr<List<T>> Function()? onLoad;
  // 加载最新
  FutureOr<List<T>> Function()? onInitLoad;

  /// 滚动条控制器
  ScrollController? scrollController;

  // 获得标题
  Widget Function(T data)? getTitle;

  // 获得标签
  List<String>? Function(T data)? getLabels;

  // 获得描述
  Widget? Function(T data)? getDesc;

  // 获得头像
  Widget? Function(T data)? getAvatar;

  // 获得角标
  int? Function(T data)? getBadge;

  // 获得内容菜单
  Widget? Function(T data)? getAction;
  // 获得占位组件
  Widget? Function()? getEmpty;

  // 点击事件
  void Function(T data, List children)? onTap;

  ListWidget(
      {super.key,
      this.getDatas,
      this.getTitle,
      this.initDatas,
      this.getLabels,
      this.getDesc,
      this.getAvatar,
      this.getAction,
      this.getEmpty,
      this.getBadge,
      this.onTap,
      this.onInitLoad,
      this.onLoad,
      this.scrollController}) {
    this.scrollController = scrollController;
    this.onInitLoad = onInitLoad;
    this.onLoad = onLoad;
    this.getTitle ??= (dynamic data) =>
        Text(data is IEntity || data is XEntity ? data.name : "暂无信息");
    this.getDesc ??= (dynamic data) =>
        Text(data is IEntity || data is XEntity ? data.remark : "暂无信息");
    this.getAvatar ??= (dynamic data) {
      return XImage.entityIcon(data, width: 40);
    };
    this.getLabels ??=
        (dynamic data) => data is IEntity ? data.groupTags : null;
  }

  @override
  _ListWidgetState createState() => _ListWidgetState<T>();
}

class _ListWidgetState<T> extends State<ListWidget> with EmptyMixin<T> {
  late dynamic datas;

  _ListWidgetState();

  @override
  void initState() {
    super.initState();
    datas = widget.initDatas ?? [];
  }

  @override
  void didUpdateWidget(ListWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (datas.hashCode != widget.initDatas.hashCode) {
      datas = widget.initDatas ?? [];
    }
  }

  bool hasInitDatas() {
    return null != widget.initDatas && (widget.initDatas?.isNotEmpty ?? false);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: !hasInitDatas()
          ? FutureBuilder<List<T>>(
              future: Future(() async {
                datas = await widget.onInitLoad?.call();
                datas ??= await widget.getDatas
                    ?.call(RoutePages.routeData.currPageData.data);
                return datas;
              }),
              initialData: datas.isEmpty ? null : datas,
              builder: (BuildContext context,
                  AsyncSnapshot<List<dynamic>> snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  datas = snapshot.data ?? [];
                  return _buildList(context);
                }
                return const Center(
                  child: CircularProgressIndicator(),
                );
              },
            )
          : _buildContentWidget(context),
    );
  }

  Widget _buildContentWidget(BuildContext context) {
    return buildEmptyWidget(
        datas.isEmpty, _buildList(context), widget.getEmpty?.call());
  }

  Widget _buildList(BuildContext context) {
    return null != widget.onLoad
        ? _buildLazyList(context)
        : _buildDefList(context);
  }

  Widget _buildLazyList(BuildContext context) {
    return XLazy(
        initDatas: datas,
        onLoad: widget.onLoad as FutureOr<List<T>> Function(),
        onInitLoad: widget.onInitLoad as FutureOr<List<T>> Function(),
        builder: (context, datas) {
          return _buildDefList(context);
        });
  }

  Widget _buildDefList(BuildContext context) {
    return ListView.separated(
        itemCount: datas.length,
        padding: const EdgeInsets.only(top: 5),
        separatorBuilder: (BuildContext context, int index) => const Divider(
              indent: 60,
              height: 5,
            ),
        itemBuilder: (BuildContext context, int index) {
          index = min(index, datas.length - 1);
          T item = datas[index];
          return ListItemWidget(
              leading: _buildAvatar(item),
              title: _buildTitle(item),
              subtitle: getSubtitle(item),
              dense: true,
              onTap: () async {
                if (null != widget.getDatas) {
                  dynamic list = await widget.getDatas?.call(item) ?? [];
                  widget.onTap?.call(item, list);
                } else {
                  widget.onTap?.call(item, []);
                }
              });
        });
  }

  Widget? _buildTitle(item) {
    List<String>? labels = widget.getLabels?.call(item);
    Widget? titleWidget = widget.getTitle?.call(item);

    Widget? actionWidget = widget.getAction?.call(item);
    if (null != titleWidget) {
      // 标题和标签在不同行模式
      titleWidget = Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Flexible(
              flex: _getTitleFlex(item, labels),
              child: DefaultTextStyle(
                  style: const TextStyle(
                    color: XColors.black,
                    fontSize: 16.5,
                    overflow: TextOverflow.ellipsis,
                  ),
                  maxLines: 1,
                  child: titleWidget),
            ),
            if (actionWidget != null) actionWidget
          ]);
    }
    return titleWidget;
  }

  Widget? _buildLabel(item, {int labelCount = 1}) {
    List<String>? labels = widget.getLabels?.call(item);
    List<Widget> labelList = getLableWidget(item, labels);
    // 标题和标签在不同行模式
    Widget widgetLabel = Wrap(children: labelList);
    return widgetLabel;
  }

  Widget? _buildAvatar(T item) {
    Widget? child = widget.getAvatar?.call(item);
    int noRead = widget.getBadge?.call(item) ?? 0;
    return BadgeTabWidget(
      body: child,
      mgsCount: noRead,
    );
    // bool isMaxVal = noRead.contains("+");
    // child = badges.Badge(
    //   ignorePointer: false,
    //   showBadge: noRead.isNotEmpty,
    //   position: badges.BadgePosition.topEnd(top: -6, end: isMaxVal ? -10 : -8),
    //   badgeStyle: isMaxVal
    //       ? const BadgeStyle(
    //           shape: BadgeShape.square,
    //           borderRadius: BorderRadius.all(Radius.circular(10)),
    //           padding: EdgeInsets.all(3.0),
    //         )
    //       : const BadgeStyle(),
    //   badgeContent: Text(
    //     noRead,
    //     style: const TextStyle(
    //       color: Colors.white,
    //       fontSize: 10,
    //       letterSpacing: 1,
    //       wordSpacing: 2,
    //       height: 1,
    //     ),
    //   ),
    //   child: child,
    // );
    // return child;
  }

  Widget? getSubtitle(dynamic item) {
    final ListTileThemeData tileTheme = ListTileTheme.of(context);
    Widget? descWdget = widget.getDesc?.call(item);
    Widget? labelWidget = _buildLabel(item, labelCount: 3);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (null != labelWidget) labelWidget,
        if (null != descWdget)
          DefaultTextStyle(
              style: tileTheme.subtitleTextStyle ??
                  const TextStyle(
                    color: XColors.chatHintColors,
                    fontWeight: FontWeight.w400,
                    overflow: TextOverflow.ellipsis,
                  ),
              maxLines: 1,
              child: Padding(
                  padding: const EdgeInsets.only(right: 20), child: descWdget)),
      ],
    );
  }

  List<Widget> getLableWidget(dynamic item, List<String>? labels) {
    List<Widget> labelWidgets = [];
    labels?.forEach((label) {
      if (label.isNotEmpty) {
        bool isTop = label == "置顶";

        Widget labelWidget = Padding(
          padding: EdgeInsets.only(left: 4.w),
          child: XText.tag(label, highlight: isTop),
        );
        labelWidgets.add(labelWidget);
      }
    });
    return labelWidgets;
  }

  int _getTitleFlex(dynamic item, List<String>? labels) {
    int flex = 1;
    if (item is IEntity &&
        item.name.isNotEmpty &&
        null != labels &&
        labels.isNotEmpty) {
      if (item.name.length > labels.last.length && labels.last.length < 4) {
        flex = 5;
      }
    }
    return flex;
  }
}
